package com.lll.securitydemo.config;

import com.lll.securitydemo.dao.PermissionDao;
import com.lll.securitydemo.dao.RolePermissionDao;
import com.lll.securitydemo.dto.RolePermissionDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * Description: 存储请求与权限的对应关系<br/>
 *
 * @author LLL<br               />;
 * @taskId <br/>
 * <br/>
 */
@Component
public class MyInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource {


    @Autowired
    private RolePermissionDao rolePermissionDao;

    @Autowired
    private PermissionDao permissionDao;

    /**
     * 决策器会用到,url对应的角色集合
     */
    private static HashMap<String, Collection<ConfigAttribute>> map = null;

    /**
     * @param
     * @return 请求的请求资源需要的角色
     * @throws IllegalArgumentException
     */
    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        if (null == map) {
            // 初始化资源对应角色
            loadResourceDefine();
        }
        // object中包含用户request相关信息
        HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
        Set<String> mapKeys = map.keySet();
        for (Iterator<String> iterator = mapKeys.iterator(); iterator.hasNext(); ) {
            String url = iterator.next();
            if (new AntPathRequestMatcher(url).matches(request)) {
                return map.get(url);
            }
        }
        return null;
    }

    private void loadResourceDefine() {
        map = new HashMap<>(16);
        // 所有的角色资源对应关系
        List<RolePermissionDTO> rolePermissionDTOS = permissionDao.getRolePermissions();
        rolePermissionDTOS.forEach(
                item -> {
                    String url = item.getUrl();
                    String roleName = item.getName();
                    ConfigAttribute configAttribute = new SecurityConfig(roleName);
                    if (map.containsKey(url)) {
                        map.get(url).add(configAttribute);
                    } else {
                        List<ConfigAttribute> list = new ArrayList<>();
                        list.add(configAttribute);
                        map.put(url, list);
                    }
                }
        );
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}
